package com.fcat.common.user.util;

import com.jcraft.jsch.*;
import com.fcat.base.common.util.CmdExecUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * @BelongsProject: fcat-project
 * @BelongsPackage: com.fcat.project.main.util
 * @Author: 
 * @CreateTime: 2020-06-06 16:12
 * @Description:
 */
@Slf4j
public class Sftp210Util {
    //@Value("${host.ip}")
    private static String ip = "120.77.204.210";
    //@Value("${host.port}")
    private static String port = "22";
    //@Value("${host.username}")
    private static String username = "root";
    //@Value("${host.password}")
    private static String password = "Tsuantone119";
    private static String projectPath = "/docker/springboot";

    private static Session session = null;
    private static Channel channel = null;


    public class SFTPConstants {
        public static final String SFTP_REQ_HOST = "host";
        public static final String SFTP_REQ_PORT = "port";
        public static final String SFTP_REQ_USERNAME = "username";
        public static final String SFTP_REQ_PASSWORD = "password";
        public static final int SFTP_DEFAULT_PORT = 22;
    }

    /**
     * 遍历项目所有模块jar包的绝对路径
     * @return
     */
    static List<String> getProjectModuleJarPaths() {
        List<String> jarPathList = new ArrayList<>();
        //遍历项目的模块
        String localProjectPath = System.getProperty("user.dir");
        File projectFile = new File(localProjectPath);
        File[] files = projectFile.listFiles();
        for (File file : files) {
            if (!file.getName().contains(".") && file.isDirectory()) {
                String str = localProjectPath + "/" + file.getName() + "/target/" + file.getName() + ".jar";
                File jarFile = new File(str);
                if (jarFile.exists()) {
                    System.err.println("存在 " + jarFile.getAbsolutePath());
                    jarPathList.add(jarFile.getAbsolutePath());
                } else {
                    System.err.println("不存在 " + jarFile.getAbsolutePath());
                }
            }
        }
        return jarPathList;
    }

    public ChannelSftp getChannel(Map<String, String> sftpDetails, int timeout) throws JSchException {
        String ftpHost = sftpDetails.get(SFTPConstants.SFTP_REQ_HOST);
        String port = sftpDetails.get(SFTPConstants.SFTP_REQ_PORT);
        String ftpUserName = sftpDetails.get(SFTPConstants.SFTP_REQ_USERNAME);
        String ftpPassword = sftpDetails.get(SFTPConstants.SFTP_REQ_PASSWORD);

        int ftpPort = SFTPConstants.SFTP_DEFAULT_PORT;
        if (port != null && !port.equals("")) {
            ftpPort = Integer.valueOf(port);
        }

        JSch jsch = new JSch(); // 创建JSch对象
        session = jsch.getSession(ftpUserName, ftpHost, ftpPort); // 根据用户名，主机ip，端口获取一个Session对象
        System.err.println("Session created.");
        if (ftpPassword != null) {
            session.setPassword(ftpPassword); // 设置密码
        }
        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config); // 为Session对象设置properties
        session.setTimeout(timeout); // 设置timeout时间
        session.connect(); // 通过Session建立链接
        System.err.println("Session connected.");

        System.err.println("Opening Channel.");
        channel = session.openChannel("sftp"); // 打开SFTP通道
        channel.connect(); // 建立SFTP通道的连接
        System.err.println("Connected successfully to ftpHost = " + ftpHost + ",as ftpUserName = " + ftpUserName
                + ", returning: " + channel);
        return (ChannelSftp) channel;
    }

    public void closeChannel() throws Exception {
        if (channel != null) {
            channel.disconnect();
        }
        if (session != null) {
            session.disconnect();
        }
    }

    //120.25.233.241",22,"root","Mictest200527");

    /**
     *
     */
    public static void uploadJarFile(List<String> moduleNameList) {
        Boolean bFilter=false;
        if(!CollectionUtils.isEmpty(moduleNameList)){
            bFilter=true;
        }
        try {
            Map<String, String> sftpDetails = new HashMap<String, String>();
            // 设置主机ip，端口，用户名，密码
            sftpDetails.put(SFTPConstants.SFTP_REQ_HOST, ip);
            sftpDetails.put(SFTPConstants.SFTP_REQ_PORT, port);
            sftpDetails.put(SFTPConstants.SFTP_REQ_USERNAME, username);
            sftpDetails.put(SFTPConstants.SFTP_REQ_PASSWORD, password);

            List<String> jarFileList=getProjectModuleJarPaths();
            if(!CollectionUtils.isEmpty(jarFileList)){
                log.info("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<-开始上传jar->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                Sftp210Util sftpUtil=new Sftp210Util();
                ChannelSftp channelSftp = sftpUtil.getChannel(sftpDetails, 60000);
                //s:::::E:\svn-53\project\trunk\fcat-project\project-netty\target\project-netty.jar
                //dst:::/root/project-netty.jar
                for (String s : jarFileList) {
                    int index=s.lastIndexOf('\\');
                    String projectName=s.substring(index+1).replaceAll(".jar","");
                    if(bFilter){
                        if(!moduleNameList.contains(projectName)){
                            continue;
                        }
                    }
                    FileInputStream inputStream = new FileInputStream(s);
                    String dst = projectPath+"/"+projectName+"/app/app.jar"; // 目标文件名
                    if (inputStream != null) {
                        log.info("sftp 正在传输文件......:"+s);
                        channelSftp.put(inputStream, dst);
                        log.info("sftp 传输文件完成:"+s+" 到centos: "+dst);
                    }
                }
                channelSftp.quit();
                channelSftp.disconnect();
                log.info("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<-上传jar完成->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                //test
//                if (channel != null) {
//                    channel.disconnect();
//                }
                ChannelShell channelShell = (ChannelShell) session.openChannel("shell");
                PipedInputStream pInputStream = new PipedInputStream();
                PipedOutputStream pOutputStream = new PipedOutputStream();
                channelShell.setInputStream(new PipedInputStream(pOutputStream));
                channelShell.setOutputStream(new PipedOutputStream(pInputStream));
                channelShell.connect();

                String shellCmd="cd "+projectPath+"\r";

                pOutputStream.write(shellCmd.getBytes(StandardCharsets.UTF_8));

                log.info("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<-重启docker服务->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                for (String s : jarFileList) {
                    int index=s.lastIndexOf('\\');
                    String projectName=s.substring(index+1).replaceAll(".jar","");
                    if(bFilter){
                        if(!moduleNameList.contains(projectName)){
                            continue;
                        }
                    }
                    shellCmd="docker-compose restart "+projectName+"\r";
//                    pOutputStream.write("docker-compose restart warehousing-main\r".getBytes(StandardCharsets.UTF_8));
                    pOutputStream.write(shellCmd.getBytes(StandardCharsets.UTF_8));
                }

                pOutputStream.flush();
                BufferedReader responseBuffer = new BufferedReader(new InputStreamReader(pInputStream));
                String msg = null;
                while((msg = responseBuffer.readLine())!=null){
                    System.out.println(msg);
                }
                responseBuffer.close();

                pInputStream.close();
                pOutputStream.close();
                channelShell.disconnect();
                //test

                sftpUtil.closeChannel();
                log.info("sftp 传输所有文件完成:");
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
//        shellTest();
        //maven 打包
        if(true) {
            log.info("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<-编译打包->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
            String localProjectPath = System.getProperty("user.dir");
            try {
                CmdExecUtil.cmdExec("cd " + localProjectPath);
                CmdExecUtil.cmdExec("mvn clean install -Dmaven.test.skip=true");
            } catch (Exception e) {
                e.printStackTrace();
                System.err.println("maven 打包失败");
                return;
            }
            log.info("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<-编译打包完成->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        }
        List<String> moduleNameList=new ArrayList<>();
//        moduleNameList.add("project-main");
        moduleNameList.add("common-user");
//        moduleNameList.add("common-fdfs");
//        moduleNameList.add("project-calculate");
//        moduleNameList.add("project-data");
//        moduleNameList.add("project-device");
//        moduleNameList.add("project-emq");
//        moduleNameList.add("project-netty");
//        //1)只上传project-main模块jar
        uploadJarFile(moduleNameList);
        //2)上传全部模块jar

        //uploadJarFile(null);
    }
}